package com.ilovepostcard.controller.server;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.ilovepostcard.R;
import com.ilovepostcard.model.Address;
import com.ilovepostcard.model.CheckNewData;
import com.ilovepostcard.model.Comment;
import com.ilovepostcard.model.Message;
import com.ilovepostcard.model.NewOrderResult;
import com.ilovepostcard.model.Order;
import com.ilovepostcard.model.Postcard;
import com.ilovepostcard.model.ShareTextConfig;
import com.ilovepostcard.model.SimpleUser;
import com.ilovepostcard.model.User;
import com.ilovepostcard.utils.JsonUtil;

import android.content.Context;
import android.util.Log;

public class PostcardResult {

    private static PostcardResult NETWORK_ERROR = new PostcardResult() {

        @Override
        public boolean isSuccess() {
            return false;
        }

        @Override
        public String getErrorMsg(Context context) {
            return context.getString(R.string.error_network_error);
        }
        
    };

    public static PostcardResult parserResult(String response) {
        try {
            /* network error or parser error */
            if (response == null)
                return NETWORK_ERROR;
            JSONObject json = new JSONObject(response);
            PostcardResult result = new PostcardResult();
            result.mMethod = json.getString(ServerSpec.ResultBase.METHOD);
            result.mResult = json.getInt(ServerSpec.ResultBase.RESULT);
            result.mErrorMsg = json.getString(ServerSpec.ResultBase.ERROR_MSG);
            if (ServerSpec.GetBuycartUrl.RESULT_METHOD.equals(result.getMethod())) {
                result.mDataString = json.getString(ServerSpec.ResultBase.DATA);
            } else if (ServerSpec.CheckAttention.RESULT_METHOD.equals(result.getMethod())
                    || ServerSpec.CheckLike.RESULT_METHOD.equals(result.getMethod())) {
                result.mDataBoolean = json.getBoolean(ServerSpec.ResultBase.DATA);
            } else if (ServerSpec.GetNewMessageCount.RESULT_METHOD.equals(result.getMethod())) {
                result.mDataInt = json.getInt(ServerSpec.ResultBase.DATA);
            } else if (ServerSpec.GetPostcard.RESULT_METHOD_FRIEND.equals(result.getMethod()) 
                    || ServerSpec.GetPostcard.RESULT_METHOD_RECOMMEND.equals(result.getMethod())
                    || ServerSpec.GetPostcard.RESULT_METHOD_MY.equals(result.getMethod())
                    || ServerSpec.GetPostcard.RESULT_METHOD_SEARCH_POSTCARD.equals(result.getMethod())
                    || ServerSpec.ListCity.RESULT_METHOD.equals(result.getMethod())
                    || ServerSpec.GetAttentionList.RESULT_METHOD.equals(result.getMethod())
                    || ServerSpec.SearchUser.RESULT_METHOD.equals(result.getMethod())
                    || ServerSpec.ListMessage.RESULT_METHOD.equals(result.getMethod())
                    || ServerSpec.ListAddress.RESULT_METHOD.equals(result.getMethod())) {
                result.mDataArray = json.getJSONArray(ServerSpec.ResultBase.DATA);
            } else if (ServerSpec.ListOrder.RESULT_METHOD.equals(result.getMethod())
                    || ServerSpec.GetOrderInfo.RESULT_METHOD.equals(result.getMethod())) {
                /* workaround, because ListOrder & GetOrderInfo have same result name. Dame it! */
                Object object = json.get(ServerSpec.ResultBase.DATA);
                if (object instanceof JSONArray) {
                    result.mDataArray = (JSONArray) object;
                } else if (object instanceof JSONObject) {
                    result.mDataObject = (JSONObject) object;
                }
            } else {
                try {
                    result.mDataObject = json.getJSONObject(ServerSpec.ResultBase.DATA);
                } catch(Exception exception) {
                    
                }
            }
            return result;
        } catch (JSONException e) {
            /* network error or parser error */
            Log.e(LOGTAG, "Parser Json Error", e);
            return NETWORK_ERROR;
        }
    }
    
    /* check the interface document for detail rules */
    public boolean isSuccess() {
//        if (ServerSpec.UserLogin.RESULT_METHOD.equals(getMethod())) {
//            return mResult > 0;
//        } else if (ServerSpec.UserRegister.RESULT_METHOD.equals(getMethod())) {
//            return mResult > 0;
//        } else if (ServerSpec.GetUserInfo.RESULT_METHOD.equals(getMethod())) {
//            return mResult == 1;
//        }
        return mResult > 0;
    }
    
    
    public String getErrorMsg(Context context) {
        if (isSystemError())
            return mErrorMsg;
        
        HashMap<Integer, Integer> errorMap = null;
        if (ServerSpec.UserLogin.RESULT_METHOD.equals(getMethod())) {
            errorMap = ServerSpec.UserLogin.ERRORS;
        } else if (ServerSpec.UserRegister.RESULT_METHOD.equals(getMethod())) {
            errorMap = ServerSpec.UserRegister.ERRORS;
        } else if (ServerSpec.GetUserInfo.RESULT_METHOD.equals(getMethod())) {
            errorMap = ServerSpec.GetUserInfo.ERRORS;
        } else if (ServerSpec.UserLoginFromOpen.RESULT_METHOD.equals(getMethod())) {
            errorMap = ServerSpec.UserLoginFromOpen.ERRORS;
        } else if (ServerSpec.UpdateUserInfo.RESULT_METHOD.equals(getMethod())) {
            errorMap = ServerSpec.UpdateUserInfo.ERRORS;
        }
        
        if (errorMap != null) {
            Integer error = errorMap.get(mResult);
            if (error != null)
                return context.getString(error.intValue());
        }
        
        return "unknown error";
    }
    
    private boolean isSystemError() {
        return mResult == 0;
    }
    
    public String getMethod() {
        return mMethod;
    }
    
    public int getResult() {
        return mResult;
    }
    
    /**
     * Only use for get user info method
     * @return
     */
    public User getUser() {
        JSONObject json = mDataObject;
        if (json == null) {
            Log.e(LOGTAG, "response error, data object is null");
            return null;
        }
        try {
            return JsonUtil.json2User(json);
        } catch(JSONException exception) {
            Log.e(LOGTAG, "response error, not user data");
            return null;
        }
    }
    
    /**
     * Only use for get postcard methods
     * public static final String ACTION_MY = "GetMyPostcard";
        public static final String ACTION_RECOMMEND = "GetHotPostcard";
        public static final String ACTION_FRIEND = "GetFriendsPostcard";
        public static final String ACTION_SEARCH_POSTCARD = "SearchPostcard";
     * @return
     */
    public ArrayList<Postcard> getPostcardList() {
        JSONArray jsonArray = mDataArray;
        if (jsonArray == null) {
            Log.e(LOGTAG, "response error, data array is null");
            return null;
        }
        int size = jsonArray.length();
        ArrayList<Postcard> list = new ArrayList<Postcard>(size + 1);
        for (int i = 0; i < size; i++) {
            try {
                JSONObject json = jsonArray.getJSONObject(i);
                Postcard postcard = JsonUtil.json2Postcard(json);
                list.add(postcard);
            } catch(JSONException e) {
                Log.e(LOGTAG, "response error, data array should contain json object");
            }
        }
        return list;
    }
    
    /**
     * Only use for get upload skey
     * @return
     */
    public String getUploadSKey() {
        JSONObject json = mDataObject;
        if (json == null) {
            Log.e(LOGTAG, "response error, data object is null");
            return null;
        }
        try {
            return json.getString("Key");
        } catch(JSONException exception) {
            Log.e(LOGTAG, "response error, not upload skey data");
            return null;
        }
    }
    
    /**
     * Only use for get can modify nickname
     * @return
     */
    public boolean canModifyNickname() {
        return getResult() == 1;
    }
    
    /**
     *  [{“Name”:”省份”,”CityItems”:[“城市”,”城市” ,”城市”]},
         {“Name”:”省份”,”CityItems”:[“城市”,”城市” ,”城市”]},
         {“Name”:”省份”,”CityItems”:[“城市”,”城市” ,”城市”]}
  ]

     * @return
     */
    public LinkedHashMap<String, ArrayList<String>> getCityTable() {
        JSONArray jsonArray = mDataArray;
        if (jsonArray == null) {
            Log.e(LOGTAG, "response error, data array is null");
            return null;
        }
        int size = jsonArray.length();
        LinkedHashMap<String, ArrayList<String>> cityTable = new LinkedHashMap<String, ArrayList<String>>(size + 1);
        for (int i = 0; i < size; i++) {
            try {
                JSONObject json = jsonArray.getJSONObject(i);
                String province = json.getString("Name");
                JSONArray cityJsonArray = json.getJSONArray("CityItems");
                int csize = cityJsonArray.length();
                ArrayList<String> citys = new ArrayList<String>(csize + 1);
                for (int j = 0; j < csize; j++) {
                    citys.add(cityJsonArray.getString(j));
                }
                cityTable.put(province, citys);
            } catch(JSONException e) {
                Log.e(LOGTAG, "response error, invalid city list json");
            }
        }
        return cityTable;
    }
    
    /**
     * Only for check new result
     * @return
     */
    public CheckNewData getCheckNewData() {
        JSONObject json = mDataObject;
        if (json == null) {
            Log.e(LOGTAG, "response error, data object is null");
            return null;
        }
        try {
            CheckNewData data = new CheckNewData();
            data.setData(mDataObject);
            return data;
        } catch(JSONException exception) {
            Log.e(LOGTAG, "response error, not check new data");
            return null;
        }
    }
    
    /**
     * Only for CheckAttention result
     * @return
     */
    public boolean getCheckAttention() {
        return mDataBoolean;
    }
    
    public ArrayList<SimpleUser> getAttentionList() {
        JSONArray jsonArray = mDataArray;
        if (jsonArray == null) {
            Log.e(LOGTAG, "response error, data array is null");
            return null;
        }
        int size = jsonArray.length();
        ArrayList<SimpleUser> simpleUserList = new ArrayList<SimpleUser>(size + 1);
        for (int i = 0; i < size; i++) {
            try {
                JSONObject json = jsonArray.getJSONObject(i);
                SimpleUser simpleUser = new SimpleUser();
                simpleUser.setData(json);
                simpleUserList.add(simpleUser);
            } catch (JSONException e) {
                Log.e(LOGTAG, "response error, invalid attention list json");
            }
        }
        return simpleUserList;
    }
    
    public Postcard getPostcardInfo() {
        JSONObject json = mDataObject;
        if (json == null) {
            Log.e(LOGTAG, "response error, data object is null");
            return null;
        }
        try {
            Postcard postcard = JsonUtil.json2Postcard(json);
            return postcard;
        } catch(JSONException exception) {
            Log.e(LOGTAG, "response error, not get postcard info data");
            return null;
        }
    }
    
    /**
     * Only for get user active time result
     * @return
     */
    public String getUserActiveTime() {
        JSONObject json = mDataObject;
        if (json == null) {
            Log.e(LOGTAG, "response error, data object is null");
            return null;
        }
        try {
            return mDataObject.getString("ActiveTime");
        } catch(JSONException exception) {
            Log.e(LOGTAG, "response error, not get user active time data");
            return null;
        }
    }
    
    /**
     * Only for get postcard comments result
     * @return
     */
    public int getPostcardCommentCount() {
        JSONObject json = mDataObject;
        if (json == null) {
            Log.e(LOGTAG, "response error, data object is null");
            return 0;
        }
        try {
            return mDataObject.getInt("TotalCount");
        } catch(JSONException exception) {
            Log.e(LOGTAG, "response error, not getPostcardCommentList data");
            return 0;
        }
    }
    
    public ArrayList<Comment> getPostcardCommentList() {
        ArrayList<Comment> comments = new ArrayList<Comment>();
        JSONObject json = mDataObject;
        if (json == null) {
            Log.e(LOGTAG, "response error, data object is null");
            return comments;
        }
        try {
            JSONArray array = mDataObject.getJSONArray("Items");
            int size = array.length();
            for (int i = 0; i < size; i++) {
                JSONObject jsonComment = array.getJSONObject(i);
                Comment comment = new Comment();
                comment.setData(jsonComment);
                comments.add(comment);
            }
        } catch(JSONException exception) {
            Log.e(LOGTAG, "response error, not getPostcardCommentList data");
        }
        return comments;
    }
    
    public ArrayList<User> getSearchUsers() {
        JSONArray jsonArray = mDataArray;
        if (jsonArray == null) {
            Log.e(LOGTAG, "response error, data array is null");
            return null;
        }
        int size = jsonArray.length();
        ArrayList<User> userList = new ArrayList<User>(size + 1);
        for (int i = 0; i < size; i++) {
            try {
                JSONObject json = jsonArray.getJSONObject(i);
                User user = JsonUtil.json2User(json);
                userList.add(user);
            } catch (JSONException e) {
                Log.e(LOGTAG, "response error, invalid attention list json");
            }
        }
        return userList;
    }
    
    public int getNewMessageCount() {
        return mDataInt;
    }

    /**
     * Only for ListMessage
     * @return
     */
    public ArrayList<Message> getMessageList() {
        JSONArray jsonArray = mDataArray;
        if (jsonArray == null) {
            Log.e(LOGTAG, "response error, data array is null");
            return null;
        }
        int size = jsonArray.length();
        ArrayList<Message> list = new ArrayList<Message>(size + 1);
        for (int i = 0; i < size; i++) {
            try {
                JSONObject json = jsonArray.getJSONObject(i);
                Message message = new Message();
                message.setData(json);
                list.add(message);
            } catch (JSONException e) {
                Log.e(LOGTAG, "response error, invalid attention list json");
            }
        }
        return list;
    }
    
    public String getUserHeadImgUrl() {
        JSONObject json = mDataObject;
        if (json == null) {
            Log.e(LOGTAG, "response error, data object is null");
            return "";
        }
        try {
            return mDataObject.getString("Url");
        } catch(JSONException exception) {
            Log.e(LOGTAG, "response error, not getPostcardCommentList data");
            return "";
        }
    }
    
    public ArrayList<Address> getAddressList() {
        JSONArray jsonArray = mDataArray;
        if (jsonArray == null) {
            Log.e(LOGTAG, "response error, data array is null");
            return null;
        }
        int size = jsonArray.length();
        ArrayList<Address> list = new ArrayList<Address>(size + 1);
        for (int i = 0; i < size; i++) {
            try {
                JSONObject json = jsonArray.getJSONObject(i);
                Address address = new Address();
                address.setData(json);
                list.add(address);
            } catch (JSONException e) {
                Log.e(LOGTAG, "response error, invalid address list json");
            }
        }
        return list;
    }
    
    @Deprecated
    public String getOrderConfirmPageUrl() {
        return mDataString;
    }
    
    
    public NewOrderResult getNewOrderResult() {
        JSONObject json = mDataObject;
        if (json == null) {
            Log.e(LOGTAG, "response error, data object is null");
            return null;
        }
        try {
            NewOrderResult result = new NewOrderResult();
            result.setData(json);
            return result;
        } catch(JSONException exception) {
            Log.e(LOGTAG, "response error, not NewOrder data info:"+exception.toString());
            return null;
        }
    }
    
    /**
     * Only use for getListOrder interface
     * @return
     */
    public ArrayList<Order> getOrderList() {
        JSONArray jsonArray = mDataArray;
        if (jsonArray == null) {
            Log.e(LOGTAG, "response error, data array is null");
            return null;
        }
        int size = jsonArray.length();
        ArrayList<Order> list = new ArrayList<Order>(size + 1);
        for (int i = 0; i < size; i++) {
            try {
                JSONObject json = jsonArray.getJSONObject(i);
                Order order = new Order();
                order.setData(json);
                list.add(order);
            } catch (JSONException e) {
                Log.e(LOGTAG, "response error, invalid order list json");
            }
        }
        return list;
    }
    
    /**
     * Only user for getOrderInfo interface
     * @return
     */
    public Order getOrderInfo() {
        JSONObject json = mDataObject;
        if (json == null) {
            Log.e(LOGTAG, "response error, data object is null");
            return null;
        }
        try {
            Order order = new Order();
            order.setData(mDataObject);
            return order;
        } catch(JSONException exception) {
            Log.e(LOGTAG, "response error, not order info data");
            return null;
        }
    }
    
    public boolean getCheckLike() {
        return mDataBoolean;
    }
    
    public Comment getLastPostcardComment() {
        JSONObject json = mDataObject;
        if (json == null) {
            Log.e(LOGTAG, "response error, data object is null");
            return null;
        }
        try {
            Comment comment = new Comment();
            comment.setData(json);
            return comment;
        } catch(JSONException exception) {
            Log.e(LOGTAG, "response error, not getLastPostcardComment data");
            return null;
        }
    }
    
    public ShareTextConfig getShareTextConfig2() {
        JSONObject json = mDataObject;
        if (json == null) {
            Log.e(LOGTAG, "response error, data object is null");
            return null;
        }
        try {
            ShareTextConfig config = new ShareTextConfig();
            config.setData(json);
            return config;
        } catch(JSONException exception) {
            Log.e(LOGTAG, "response error, not ShareTextConfig data");
            return null;
        }
    }
    
    public String getBuyChartUrl() {
        return mDataString;
    }
    
    private static final String LOGTAG = "PostcardServer";

    private String mMethod;
    private int mResult;
    private String mErrorMsg;
    private JSONObject mDataObject;
    private JSONArray mDataArray;
    private boolean mDataBoolean;
    private int mDataInt;
    private String mDataString;

    private PostcardResult() {

    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

}
